package org.dromara.system.service.impl;

import com.google.common.collect.Lists;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.SysUser;
import org.dromara.system.mapper.SysUserMapper;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.dromara.system.domain.bo.PayTypeBo;
import org.dromara.system.domain.vo.PayTypeVo;
import org.dromara.system.domain.PayType;
import org.dromara.system.mapper.PayTypeMapper;
import org.dromara.system.service.IPayTypeService;

import java.util.*;
import java.util.function.Consumer;

/**
 * 支付平台Service业务层处理
 *
 * @author Gavino
 * @date 2024-10-22
 */
@RequiredArgsConstructor
@Service
public class PayTypeServiceImpl implements IPayTypeService {

    private final PayTypeMapper baseMapper;
    private final SysUserMapper sysUserMapper;
    private static final String  pay_type_key = "pay_type_key:";
    /**
     * 查询支付平台
     *
     * @param typeId 主键
     * @return 支付平台
     */
    @Override
    public PayTypeVo queryById(Long typeId){
        PayTypeVo payTypeVo = RedisUtils.getCacheObject(pay_type_key + typeId);
        if(payTypeVo == null) {
            payTypeVo = baseMapper.selectVoById(typeId);
            RedisUtils.setCacheObject(pay_type_key + typeId, payTypeVo);
        }
        return payTypeVo;
    }

    /**
     * 分页查询支付平台列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 支付平台分页列表
     */
    @Override
    public TableDataInfo<PayTypeVo> queryPageList(PayTypeBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<PayType> lqw = buildQueryWrapper(bo);
        Page<PayTypeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的支付平台列表
     *
     * @param bo 查询条件
     * @return 支付平台列表
     */
    @Override
    public List<PayTypeVo> queryList(PayTypeBo bo) {
        LambdaQueryWrapper<PayType> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<PayType> buildQueryWrapper(PayTypeBo bo) {
        LambdaQueryWrapper<PayType> lqw = Wrappers.lambdaQuery();

        // 普通用户只能查看自己的支付平台 + 公共可见的平台
        if (!LoginHelper.isSuperAdmin()) {
            lqw.and(query -> {
                query.eq(PayType::getCommon, 1);

                Long userId = LoginHelper.getUserId();
                if (!LoginHelper.isAgent()) {
                    userId = LoginHelper.getLoginUser().getAgentId();
                }
                if (userId != null) {
                    SysUser user = sysUserMapper.selectById(userId);
                    if (StringUtils.isNotEmpty(user.getPayType())) {
                        List<Long> typeIds = Lists.newArrayList(user.getPayType().split(",")).stream().map(Long::valueOf).toList();
                        if (!typeIds.isEmpty()) {
                            query.or().in(PayType::getTypeId, typeIds);
                        }
                    }
                }
            });
        }

        lqw.eq(bo.getCommon()!= null, PayType::getCommon, bo.getCommon());
        lqw.eq(bo.getTypeId() != null, PayType::getTypeId, bo.getTypeId());
        lqw.like(StringUtils.isNotBlank(bo.getName()), PayType::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getCode()), PayType::getCode, bo.getCode());
        lqw.eq(bo.getStatus() != null, PayType::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增支付平台
     *
     * @param bo 支付平台
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(PayTypeBo bo) {
        PayType add = MapstructUtils.convert(bo, PayType.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        PayTypeVo payTypeVo = baseMapper.selectVoById(add.getTypeId());
        RedisUtils.setCacheObject(pay_type_key + payTypeVo.getTypeId(), payTypeVo);
        return flag;
    }

    /**
     * 修改支付平台
     *
     * @param bo 支付平台
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(PayTypeBo bo) {
        PayType update = MapstructUtils.convert(bo, PayType.class);
        validEntityBeforeSave(update);
        int num = baseMapper.updateById(update);
        PayTypeVo payTypeVo = baseMapper.selectVoById(bo.getTypeId());
        RedisUtils.setCacheObject(pay_type_key + payTypeVo.getTypeId(), payTypeVo);
        return num > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(PayType entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除支付平台信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        for (Long id : ids) {
            RedisUtils.deleteKeys(pay_type_key + id);
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
